#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/time.h>

struct BoxMullerState{
	double x1, x2, w, y1, y2;
     int useLast;
     struct drand48_data random;
};

/* Inicializando a estrutura*/
void initBoxMullerState(struct BoxMullerState* state){
     state->random.__init = 0;
     state->useLast = 0;
        
     struct timeval now;
	gettimeofday(&now, NULL);
	state->random.__x[0] = now.tv_usec;
}

/*Calculando o número aleatório de distribuição normal, com média 0 e variância de 1*/
double boxMullerRandom(struct BoxMullerState* state){
	if (state->useLast){
		state->y1 = state->y2;
          state->useLast = 0;
     }
	else{
		do{
			drand48_r(&state->random, &state->x1);
			state->x1 = 2.0 * state->x1 - 1.0;
			drand48_r(&state->random, &state->x2);
			state->x2 = 2.0 * state->x2 - 1.0;
			state->w = state->x1 * state->x1 + state->x2 * state->x2;
		}while (state->w >= 1.0);
		state->w = sqrt((-2.0 * log(state->w)) / state->w);
		state->y1 = state->x1 * state->w;
		state->y2 = state->x2 * state->w;
		state->useLast = 1;
	}
	return state->y1;
}


int main (void){
	double s, e, r, ro, tempo, t, *trials, media, desvio, intervalo, maximo, minimo;
	int i, n;
	struct BoxMullerState state;

	/*Leitura dos paramêtros*/
	scanf("%lf %lf %lf %lf %lf %d",&s, &e, &r, &ro, &tempo, &n);
	/*Alocação do vetor que irá armazenar os valores obtidos pelo blackscholes*/ 
	trials = (double *)malloc (sizeof(double)*(n+1));

	/*inicializando as variáveis*/
	media=0.0;
	desvio = 0.0;
	initBoxMullerState(&state);

	/*algoritmo do blackscholes*/
	for(i =0; i<= n-1; i++){
		t = s*exp((r-(ro*ro)/2)*tempo+ro*sqrt(tempo)*boxMullerRandom(&state));
		trials[i] = exp(-r*tempo)*fmax(t-e, 0.0);
		media += trials[i];
	}
	
	/*calculo da média*/
	media = media/n;

	/*calculo do desvio padrão*/
	for(i =0; i<= n-1; i++){
		desvio += pow(trials[i]-media, 2);
	}
	desvio = sqrt(desvio/(n-1));
	
	/*calculo do intervalo de confiança*/
	intervalo = 1.96*(desvio/sqrt(n));

	/*calculo do mínimo e máximo*/
	minimo = media - intervalo;
	maximo = media + intervalo;

	/*impressão*/
	printf("S \t%.0lf\n", s);
	printf("E \t%.0lf\n", e);
	printf("r \t%.0lf\n", r);
	printf("sigma \t%.0lf\n", ro); 
	printf("T \t%.0lf\n", tempo);
	printf("M \t%d\n", n);
	printf("Confidence interval: (%.4lf, %.4lf)\n",minimo, maximo);
	
	return 1;
}
